<template>
  <!-- 密码修改表单组件 -->
  <!-- 使用Element Plus的表单组件实现密码修改功能 -->
  <el-form ref="passwordForm" label-width="70px" :model="form" :rules="rules">
    <!-- 旧密码输入字段 -->
    <el-form-item label="旧密码" prop="oldPassword">
      <el-input type="password" v-model="form.oldPassword" />
    </el-form-item>
    <!-- 新密码输入字段 -->
    <el-form-item label="新密码" prop="newPassword">
      <el-input type="password" v-model="form.newPassword" />
    </el-form-item>
    <!-- 确认密码输入字段 -->
    <el-form-item label="密码确认" prop="confirmPassword">
      <el-input type="password" v-model="form.confirmPassword" />
    </el-form-item>
    <!-- 操作按钮区域 -->
    <el-form-item>
      <el-button @click="clearData()">重置</el-button>
      <el-button type="primary" @click="confirm()">确认修改</el-button>
    </el-form-item>
  </el-form>
</template>

<script setup lang="ts">
/**
 * Password.vue - 密码修改页面组件
 * 提供用户修改账户密码的功能，包括旧密码验证、新密码设置和确认密码校验
 * 
 * 主要功能：
 * - 允许用户输入旧密码、新密码和确认密码
 * - 实现密码格式验证和两次输入一致性校验
 * - 提供重置表单和提交修改密码的操作
 * - 与后端API交互完成密码修改
 * 
 * 组件关系：
 * - 父组件：Setting页面（设置页面）
 * - 使用组件：Element Plus的Form、FormItem、Input和Button组件
 * 
 * 技术要点：
 * - 使用Vue 3组合式API（script setup）
 * - 基于TypeScript进行类型定义
 * - 集成Vuex获取用户信息
 * - 使用Element Plus表单验证功能
 * - 通过HTTP请求与后端交互
 */
import { ref, computed, reactive } from "vue"; // Vue 3组合式API核心函数
import { useStore } from "vuex"; // 用于访问全局状态管理
import mixin from "@/mixins/mixin"; // 包含通用方法的混合器
import { HttpManager } from "@/api"; // 封装API请求的管理工具
// 导入密码验证器
import { validatePassword } from "@/enums"; // 密码格式验证工具函数
import { ElMessage, type ElForm } from "element-plus";

// 类型定义
interface FormData {
  oldPassword: string; // 用户当前密码
  newPassword: string; // 用户希望设置的新密码
  confirmPassword: string; // 再次输入的新密码，用于确认
}

interface ResponseBody {
  success: boolean; // 操作是否成功
  message: string; // 操作结果消息
  type: string; // 消息类型（success, error等）
}
// 获取Vuex存储实例
const store = useStore();


// 从混合器中解构返回上一页的方法
const { goBack } = mixin();

// 表单数据响应式对象，存储密码修改表单的输入值
const form = reactive<FormData>({
  oldPassword: "", // 用户当前密码
  newPassword: "", // 用户希望设置的新密码
  confirmPassword: "", // 再次输入的新密码，用于确认
});

// 计算属性：从Vuex存储中获取当前用户ID
const userId = computed(() => store.getters.userId);
// 计算属性：从Vuex存储中获取当前用户名
const userName = computed(() => store.getters.username);

/**
 * 确认密码验证函数
 * 用于验证确认密码是否与新密码一致
 * @param rule 验证规则对象（Element Plus表单验证规则）
 * @param value 当前输入的确认密码值
 * @param callback 验证结果回调函数，无返回值
 */
const validateCheck = (rule: any, value: any, callback: any) => {
  // 检查密码是否为空
  if (value === "") {
    callback(new Error("密码不能为空"));
  } 
  // 检查两次输入的密码是否一致
  else if (value !== form.newPassword) {
    callback(new Error("请输入正确密码"));
  } 
  // 验证通过
  else {
    callback();
  }
};

// 表单验证规则配置，定义各字段的验证逻辑
const rules = reactive({
  oldPassword: [{ validator: validatePassword, trigger: "blur", min: 3 }], // 旧密码验证规则：使用密码验证器，失去焦点时触发，最小长度为3
  newPassword: [{ validator: validatePassword, trigger: "blur", min: 3 }], // 新密码验证规则：使用密码验证器，失去焦点时触发，最小长度为3
  confirmPassword: [{ validator: validateCheck, trigger: "blur", min: 3 }], // 确认密码验证规则：使用自定义验证函数，失去焦点时触发，最小长度为3
});

/**
 * 重置表单数据函数
 * 清空表单中所有密码输入字段的值
 * @returns {Promise<void>} 无返回值的Promise
 */
async function clearData() {
  form.oldPassword = "";
  form.newPassword = "";
  form.confirmPassword = "";
}

const passwordForm = ref<InstanceType<typeof ElForm>>();

/**
 * 确认修改密码函数
 * 执行密码修改流程，包括表单验证、数据收集和API请求
 * @returns {Promise<void>} 无返回值的Promise
 */
async function confirm() {
  let canRun = true;
  
  // 执行表单验证
  passwordForm.value.validate((valid: boolean) => {    
    if (!valid) return new Promise(()=> canRun = false);
  });
  
  // 若验证失败则中断执行
  if (!canRun) return;

  // 收集表单数据和用户信息
  const id = userId.value;
  const username = userName.value;
  const password = form.newPassword;

  // 发送密码修改请求到服务器
  const result = (await HttpManager.updateUserPassword({id,username,oldPassword: form.oldPassword,password})) as ResponseBody;
  
  // 显示操作结果消息
  ElMessage({
    message: result.message,
    type: result.type as any,
  });
  
  // 若密码修改成功，则返回上一页
  if (result.success) goBack();
}
</script>

<style></style>
